﻿using UnityMethods.Extend;
using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;
using System;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using UnityTemplate.Services.Interface;

namespace UnityTemplate.Services.Implement
{
    public class JwtAuthorizeService : IJwtAuthorizeService
    {
        public string CreateToken(IdentityUser user, string securityKey)
        {
            var jwtTokenHandler = new JwtSecurityTokenHandler();

            // 从 appsettings 中获得我们的 secret 
            var key = Encoding.ASCII.GetBytes(securityKey);

            // 定义我们的 token descriptor
            // 我们需要使用 claims （token 中的属性）给出关于 token 的信息，它们属于特定的用户，
            // 因此，可以包含用户的 Id、名字、邮箱等。
            // 好消息是，这些信息由我们的服务器和 Identity framework 生成，它们是有效且可信的。
            var tokenDescriptor = new SecurityTokenDescriptor
            {
                Subject = new ClaimsIdentity(new[]
                {
                    new Claim(ClaimTypes.Role, "Client"),
                    new Claim("UserId", user.Id),
                    new Claim("UserName", user.UserName.IsEmpty() ? Guid.NewGuid().ToString() : user.UserName),
                    new Claim("Email", user.Email.IsEmpty() ? Guid.NewGuid().ToString() : user.Email),
                    /* Jti 用于刷新 token*/
                    new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
                }),

                /* token 的过期时间需要缩短，并利用 refresh token 来保持用户的登录状态*/
                Expires = DateTime.UtcNow.AddDays(1),
                /* token */
                SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)
            };

            var token = jwtTokenHandler.CreateToken(tokenDescriptor);
            var jwtToken = jwtTokenHandler.WriteToken(token);

            return jwtToken;
        }
    }
}
